題目要我把重疊的區間合併並返回不重疊的區間。
了解題目要求:
題目給一組區間,每個區間包含起點和終點,目的是把所有 重疊 區間合併,合併後的區間不能重疊,最後要返回合併後的區間結果,思考:重點是檢查兩個區間是不是重疊,如果區間 A 的結束點大於或等於區間 B 的開始點,就表示這兩個區間重疊,應把它們合併,合併後的區間是從 A 和 B 的最小開始點到它們的最大結束點。
困難:
怎樣高效處理大量區間?(可能有多到 10^4 個區間)怎麼識別和合併所有重疊區間?
思路:
排序,先把所有區間一照它起始點進行排序,這樣就可以從頭到尾線性掃描區間,再合併區間,從第一個區間開始,不斷檢查下一個區間是不是跟當前區間重疊,如果重疊,就合併;如果沒重疊,就把當前區間放到結果列表,再開始檢查下一個區間,每次合併,只要更新當前區間的結束點成最大結束點。
排序:將區間按照開始點排序。
遍歷合併:用一個結果列表儲存合併後的區間,逐一檢查當前區間和下一個區間是不是重疊,合併它們或把它分開存入結果。
程式碼:
class Solution(object):
def merge(self, intervals):
"""
:type intervals: List[List[int]]
:rtype: List[List[int]]
"""
#先對區間排序,根據每個區間的開始點排序
intervals.sort(key=lambda x: x[0])
#結果列表
merged = []
for interval in intervals:
# 如果結果列為空,或當前區間和結果列表中最後一個區間不重疊
if not merged or merged[-1][1] < interval[0]:
merged.append(interval)
else:
# 如果有重疊,合併區間,更新結果列表最後一個區間的結束點
merged[-1][1] = max(merged[-1][1], interval[1])
return merged
解釋程式碼:
排序:intervals.sort(key=lambda x: x[0]) 會根據每個區間的開始點對 intervals 做排序,讓後面的合併可以照區間順序進行,遍歷區間,檢查每個區間,如果結果列表是空,或當前區間和結果列表中的最後一個區間不重疊,就把當前區間加到結果列,不然就更新結果列中的最後一個區間,把它終點設成兩個重疊區間中的最大終點。
關鍵步驟:
排序區間是為了能線性掃描合併重疊區間,用 merged[-1][1] < interval[0] 檢查是否重疊,用 max(merged[-1][1], interval[1]) 更新合併後區間的終點。
優點:
這種解法是效率比較好,因為只要排序區間(時間複雜度是 O(n log n)),之後再做一次線性掃描合併區間(時間複雜度是 O(n))。所以總時間複雜度是 O(n log n),還算合理,尤其在區間數量高達 10^4 的時候。
心得:
這題,合併區間的關鍵在怎麼有效地處理重疊情況,透過排序區間,可以簡單地依次檢查和合併,不需要進行額外的複雜操作,雖然說姐花了一些時間,但好像沒有之前,雖然說姐花了一些時間,但好像沒有之前那麼煩躁,感覺漸漸變成一種習慣,終於過了三分之一。